package etcd

import (
	"context"
	"encoding/json"
	"fmt"
	"time"

	"github.com/coreos/etcd/storage/storagepb"
	"github.com/sirupsen/logrus"
	"go.etcd.io/etcd/clientv3"

	"logproject/model"
	"logproject/tailfile"
)

type EtcdObj struct {
	client *clientv3.Client
}

func NewEtcdClient() *EtcdObj {
	return &EtcdObj{}
}

func Init(address []string) (etcdobj *EtcdObj, err error) {
	etcdobj = NewEtcdClient()
	etcdobj.client, err = clientv3.New(clientv3.Config{Endpoints: address,
		DialTimeout: time.Second * 5})
	if err != nil {
		fmt.Printf("client new failed err:", err)
		return
	}

	return
}

//获取日志收集配置
func (e *EtcdObj) GetConf(key string) (collectEntryList []model.CollerctEntry) {
	ctx, cancel := context.WithTimeout(context.Background(), time.Second*2)
	defer cancel()
	resp, err := e.client.Get(ctx, key)
	if err != nil {
		logrus.Error("get conf failed ", key, err)
		return nil
	}
	if len(resp.Kvs) == 0 {
		logrus.Error("no conf in etcd")
		return
	}
	ret := resp.Kvs[0]
	err = json.Unmarshal(ret.Value, &collectEntryList)
	if err != nil {
		logrus.Error("etcdGetConf failed err:", err)
		return nil
	}
	return collectEntryList
}

//监控etcd配置变化
func (e *EtcdObj) WatchConf(key string, tailfstructForSave *tailfile.Tailf) {

	wCh := e.client.Watch(context.Background(), key)
	for resp := range wCh {
		for _, evt := range resp.Events {
			NewCollectEntryList := []model.CollerctEntry{}
			if evt.Type == storagepb.DELETE {
				tailfstructForSave.Changes = true
				tailfstructForSave.EtcdConf = NewCollectEntryList
				logrus.Warningf("etcd deled key:%s!!!", key)
				continue
			}
			//fmt.Printf("type:%s key:%s value:%s\n",evt.Type,evt.Kv.Key,evt.Kv.Value)
			err := json.Unmarshal(evt.Kv.Value, &NewCollectEntryList)
			if err != nil {
				logrus.Errorf("Watch etcdConf Unmarshal failed,err:%v", err)
				continue
			}
			//将序列化得到的新配置传给tail
			tailfstructForSave.Changes = true
			tailfstructForSave.EtcdConf = NewCollectEntryList
		}
	}
}
